﻿//
// *************************************************************************************
// WP-Framework
// 
// Developed by
// Lukas Kretschmar (lkretschmar.dev@bluewin.ch)
//
// Switzerland, Copyright (c) 2013 lkretschmar
// This content is released under the MIT License (http://opensource.org/licenses/MIT).
//     
// *************************************************************************************
//
//



using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Linq;
using KretschIT.WP_Fx.EasyMoq.Generator.Items;
using KretschIT.WP_Fx.EasyMoq.Generator.Tests.Helpers.Objects;
using System;
using System.Collections.Generic;
using KretschIT.WP_Fx.Testing;

namespace KretschIT.WP_Fx.EasyMoq.Generator.Tests.Items
{
    [TestClass]
    public class NamingFactoryTest
    {
        private INamingFactory factory;

        [TestInitialize]
        public void Init()
        {
            var types = new List<Type> { typeof(ITestObject), typeof(ITestSimpleGenericObject<string>), typeof(ITestComplexGenericObject<int, string, ITestObject>) };
            this.factory = new NamingFactory(types);
        }

        [TestMethod]
        public void Test_MockableNameFactoryCtor_NullArgument()
        {
            ExceptionAssert.Throws<ArgumentNullException>(() =>
                {
                    new NamingFactory(null);
                });
        }

        [TestMethod]
        public void Test_CreateMockableNameFor_NonGeneric()
        {
            var name = this.factory.CreateMockableNameFor(typeof(ITestObject));
            Assert.AreEqual("TestObjectMockable", name);
        }

        [TestMethod]
        public void Test_GetInterceNameOf_NonGeneric()
        {
            var name = this.factory.GetNormalizedNameOf(typeof(ITestObject));
            Assert.AreEqual("KretschIT.WP_Fx.EasyMoq.Generator.Tests.Helpers.Objects.ITestObject", name);
        }

        [TestMethod]
        public void Test_CreateMockableNameFor_SimpleGeneric()
        {
            var name = this.factory.CreateMockableNameFor(typeof(ITestSimpleGenericObject<string>));
            Assert.AreEqual("TestSimpleGenericObject1Mockable", name);
        }

        [TestMethod]
        public void Test_GetInterfaceNameOf_SimpleGeneric()
        {
            var name = this.factory.GetNormalizedNameOf(typeof(ITestSimpleGenericObject<string>));
            Assert.AreEqual("KretschIT.WP_Fx.EasyMoq.Generator.Tests.Helpers.Objects.ITestSimpleGenericObject", name);
        }

        [TestMethod]
        public void Test_GetInterfaceNameOf_SimpleGeneric_ButOtherNamespace()
        {
            var types = new List<Type> { typeof(ITestSimpleGenericObject<string>), typeof(Helpers.OtherObjects.ITestSimpleGenericObject<string>) };
            var factory = new NamingFactory(types);
            var name = factory.GetNormalizedNameOf(typeof(ITestSimpleGenericObject<string>));
            var otherName = factory.GetNormalizedNameOf(typeof(Helpers.OtherObjects.ITestSimpleGenericObject<string>));

            Assert.AreEqual("KretschIT.WP_Fx.EasyMoq.Generator.Tests.Helpers.Objects.ITestSimpleGenericObject", name);
            Assert.AreEqual("KretschIT.WP_Fx.EasyMoq.Generator.Tests.Helpers.OtherObjects.ITestSimpleGenericObject", otherName);
        }

        [TestMethod]
        public void Test_CreateMockableNameFor_SimpleGeneric_ButOtherNamespace()
        {
            var types = new List<Type> { typeof(ITestSimpleGenericObject<string>), typeof(Helpers.OtherObjects.ITestSimpleGenericObject<string>) };
            var factory = new NamingFactory(types);
            var name = factory.CreateMockableNameFor(typeof(ITestSimpleGenericObject<string>));
            var otherName = factory.CreateMockableNameFor(typeof(Helpers.OtherObjects.ITestSimpleGenericObject<string>));

            Assert.AreEqual("TestSimpleGenericObject1Mockable", name);
            Assert.AreEqual("TestSimpleGenericObject1_1_Mockable", otherName);
        }

        [TestMethod]
        public void Test_CreateMockableNameFor_NonGeneric_MultipleTimes()
        {
            var name1 = this.factory.CreateMockableNameFor(typeof(ITestObject));
            var name2 = this.factory.CreateMockableNameFor(typeof(ITestObject));
            var name3 = this.factory.CreateMockableNameFor(typeof(ITestObject));

            Assert.AreEqual("TestObjectMockable", name1);
            Assert.AreEqual("TestObjectMockable", name2);
            Assert.AreEqual("TestObjectMockable", name3);
        }

        [TestMethod]
        public void Test_CreateMockabelNameFor_SimpleGeneric_MultipleTimes()
        {
            var types = new List<Type> { typeof(ITestSimpleGenericObject<string>), typeof(Helpers.OtherObjects.ITestSimpleGenericObject<string>) };
            var factory = new NamingFactory(types);
            var name1 = factory.CreateMockableNameFor(typeof(ITestSimpleGenericObject<string>));
            var name2 = factory.CreateMockableNameFor(typeof(ITestSimpleGenericObject<string>));
            var otherName1 = factory.CreateMockableNameFor(typeof(Helpers.OtherObjects.ITestSimpleGenericObject<string>));
            var otherName2 = factory.CreateMockableNameFor(typeof(Helpers.OtherObjects.ITestSimpleGenericObject<string>));

            Assert.AreEqual("TestSimpleGenericObject1Mockable", name1);
            Assert.AreEqual("TestSimpleGenericObject1Mockable", name2);
            Assert.AreEqual("TestSimpleGenericObject1_1_Mockable", otherName1);
            Assert.AreEqual("TestSimpleGenericObject1_1_Mockable", otherName2);
        }

        [TestMethod]
        public void Test_CreateMockableNameFor_ComplexGeneric()
        {
            var name = this.factory.CreateMockableNameFor(typeof(ITestComplexGenericObject<int, string, ITestObject>));
            Assert.AreEqual("TestComplexGenericObject3Mockable", name);
        }

        [TestMethod]
        public void Test_GetInterfaceNameOf_ComplexGeneric()
        {
            var name = this.factory.GetNormalizedNameOf(typeof(ITestComplexGenericObject<int, string, ITestObject>));
            Assert.AreEqual("KretschIT.WP_Fx.EasyMoq.Generator.Tests.Helpers.Objects.ITestComplexGenericObject", name);
        }

        [TestMethod]
        public void Test_GetUsedTypesOf()
        {
            var usedTypes = this.factory.GetUsedTypesOf(typeof(ITestObject));
            Assert.AreEqual(5, usedTypes.Count());
        }

        [TestMethod]
        public void Test_GetUsedTypesOf_Null()
        {
            var usedTypes = this.factory.GetUsedTypesOf(null);
            Assert.AreEqual(0, usedTypes.Count());
        }

        [TestMethod]
        public void Test_GetUsedTypesOf_UnknownType()
        {
            var usedTypes = this.factory.GetUsedTypesOf(typeof(object));
            Assert.AreEqual(0, usedTypes.Count());
        }
    }
}
